package com.xhwl.centiotdata.suppliersystem.lifang;

import cn.hutool.http.HttpException;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xhwl.centiotdata.pojo.constant.LiFangConstant;
import com.xhwl.centiotdata.pojo.constant.StrConstant;
import com.xhwl.centiotdata.utils.RedisUtils;
import com.xhwl.common.exception.ApplicationException;
import com.xhwl.common.exception.BusinessException;
import com.xhwl.common.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @Author: yanyixiong
 * @Description:
 * @Date: create in 10:51 2022/7/11
 */
@Component
public class GeneralLiFangHandler {

    private static final Logger log = LoggerFactory.getLogger(GeneralLiFangHandler.class);

    @Autowired
    private RedisUtils redisUtils;

    private static ReentrantLock lock = new ReentrantLock();

    public JSONObject post(String url, Object params, Integer projectId, Integer productId, String ipAndPort, String admin, String password){
        String path = new StringBuffer(ipAndPort).append(LiFangConstant.PROJECT).append(url).toString();
        String result = null;
        String jsonParam = JSON.toJSONString(params);
        jsonParam = jsonParam.replace("\\r\\n", "");


        log.info("请求立方参数信息:{}", jsonParam);
        try {
            Map<String, String> header = new HashMap<>();
            header.put(LiFangConstant.ACCESS_TOKEN, this.getToken(projectId, productId, ipAndPort, admin, password));
            log.info("header info:{}", header);
            result = HttpRequest
                    .post(path)
                    .addHeaders(header)
                    .body(jsonParam)
                    .setConnectionTimeout(3000)
                    .setReadTimeout(5000)
                    .execute()
                    .body();
        } catch (HttpException e) {
            log.error("【LiFang post exception】path:{};params:{}", path, jsonParam);
            e.printStackTrace();
            throw new ApplicationException();
        }
        if (StringUtils.isEmpty(result)) {
            log.error("【LiFang post】path:{};params:{};result is null!", path, JSON.toJSONString(params));
            throw new BusinessException();
        }
        JSONObject jsonObject = JSON.parseObject(result);
        log.info("【LiFang post】path:{};params:{};result:{}", path, JSON.toJSONString(params), jsonObject);
        return jsonObject;

    }

    public String getToken(Integer projectId,Integer productId,String ipAndPort,String admin,String password){
        String accessToken = null;
        lock.lock();
        try {
            String key = new StringBuffer(StrConstant.SUPPLIER_SYSTEM_TOKEN).append("-").append(projectId).append("-").append(productId).toString();
            Object value = redisUtils.get(key);
            if (value == null) {
                accessToken = this.requestAccessToken(ipAndPort, admin, password);
                accessToken = accessToken.replace("\r\n", "");
                // 设置或更新过期时间
                redisUtils.setWithMinute(key, accessToken, 10);
            } else {
                accessToken = (String) value;
            }
        } catch (Exception e) {
            log.error("【LiFang getAccessToken exception】projectId:{}", projectId);
            e.printStackTrace();
            throw new ApplicationException();
        } finally {
            lock.unlock();
        }
        return accessToken;
    }

    private String requestAccessToken(String ipAndPort, String admin, String password) {
        String path = new StringBuffer(ipAndPort).append(LiFangConstant.PROJECT).append(LiFangConstant.TOKEN_URL).toString();
        String result = null;
        Map<String,Object> params = new HashMap<>();
        params.put("admin",admin);
        params.put("password",password);
        try {
            result = HttpUtil.createPost(path)
                    .body(JSONObject.toJSONString(params))
                    .setConnectionTimeout(3000)
                    .setReadTimeout(5000)
                    .execute()
                    .body();
        } catch (HttpException e) {
            log.error("【LiFang requestToken exception】path:{};admin:{};password:{}", path, admin, password);
            e.printStackTrace();
            throw new ApplicationException();
        }
        if (StringUtils.isEmpty(result)) {
            log.error("【LiFang requestToken result is null】path:{};admin:{};password:{}", path, admin, password);
            throw new BusinessException();
        }
        JSONObject resultObject = JSON.parseObject(result);
        JSONObject responseData = resultObject.getJSONObject("responseData");
        if (Objects.isNull(responseData)) {
            log.error("【LiFang requestToken result is null】path:{};admin:{};password:{}", path, admin, password);
            throw new BusinessException();
        }
        return responseData.getString("token");
    }

}
